namespace Pdf
{
	template <class T> 
	SmartPtr<T>::SmartPtr() : px(0)
	{	}

	template <class T> 
	SmartPtr<T>::SmartPtr(T *p, bool addref = true ) : px(p)
	{
		if( px != 0 && addref) 
			px->addref();
	}

	template <class T> 
	SmartPtr<T>::SmartPtr(const SmartPtr &rhs): px( rhs.px )
	{
		if( px != 0 ) 
			px->addref();
	}

	template <class T> 
	SmartPtr<T>::~SmartPtr()
	{
		if( px != 0 ) 
			px->release();
	}

	template <class T>
	template <class U> 
	SmartPtr<T>::SmartPtr(const SmartPtr<U> &rhs) : px( static_cast<T*>( rhs.get() ) )
	{
		if( px != 0 )
			px->addref();
	}

	template <class T> 
	template <class U> 
	SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<U> &rhs)
	{
		ThisType(rhs).swap(*this);
		return *this;
	}

	template <class T> 
	SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr &rhs)
	{
		ThisType(rhs).swap(*this);
		return *this;
	}

	template <class T> 
	SmartPtr<T>& SmartPtr<T>::operator=(T *rhs)
	{
		ThisType(rhs).swap(*this);
		return *this;
	}

	template <class T> 
	void SmartPtr<T>::reset()
	{
		ThisType().swap( *this );
	}

	template <class T> 
	void SmartPtr<T>::reset(T *rhs)
	{
		ThisType(rhs).swap( *this );
	}

	template <class T> 
	T* SmartPtr<T>::get() const
	{
		return px;
	}

	template <class T> 
	T& SmartPtr<T>::operator*() const
	{
		assert( px != 0 );
		return *px;
	}

	template <class T> 
	T* SmartPtr<T>::operator->() const
	{
		assert( px != 0 );
		return px;
	}

	template <class T> 
	SmartPtr<T>::operator UnspecifiedBoolType() const throw()
	{
		return px == 0 ? 0 : &ThisType::px;
	}

	template <class T> 
	bool SmartPtr<T>::operator! () const throw()
	{
		return px == 0;
	}

	template <class T> 
	void SmartPtr<T>::swap(SmartPtr &rhs)
	{
		T* tmp = px;
		px = rhs.px;
		rhs.px = tmp;
	}
}